<template>
  <Row type="flex" :gutter="gutter">
    <Col span="8">
      <Select
        ref="province"
        v-model="provinceId"
        clearable filterable
        @on-change="onProvinceChange"
        @on-open-change="visible => this.handleClose(visible, 'provinceId', 'province')"
        :label-in-value="true"
        placeholder="省">
        <Option v-for="p in provinces" :key="p.id" :value="p.id + '$' + p.region_code">{{p.name}}</Option>
      </Select>
    </Col>

    <Col span="8">
      <Select
        ref="city"
        v-model="cityId"
        clearable filterable
        @on-change="onCityChange"
        @on-open-change="visible => this.handleClose(visible, 'cityId', 'city')"
        :label-in-value="true"
        placeholder="市">
        <Option v-for="c in cities" :key="c.id" :value="c.id + '$' + c.region_code">{{c.name}}</Option>
      </Select>
    </Col>

    <Col span="8">
      <Select
        ref="district"
        v-model="districtId"
        clearable filterable
        @on-change="onDistrictChange"
        @on-open-change="visible => this.handleClose(visible, 'districtId', 'district')"
        :label-in-value="true"
        placeholder="区">
        <Option v-for="a in districts" :key="a.id" :value="a.id + '$' + a.region_code">{{a.name}}</Option>
      </Select>
    </Col>
  </Row>
</template>

<script>
import dataCenter from '@/libs/dataCenter'
/**
     * 一行三列地址选择器
     * 双向绑定 省市区
     * demo:
        import areaSelector from '@/views/my-components/area-selector/areaSelector.vue';
        <area-selector
            ref="areaSelector"
            :province.sync="form.province"
            :city.sync="form.city"
            :district.sync="form.district"
            ></area-selector>
        api:
        编辑时触发更新 this.$refs.areaSelector.setState(provinceName cityName, districtName);
        清除省市区数据 this.$refs.areaSelector.clearState();
     */
export default {
  name: 'area-selector',
  props: {
    province: String,
    city: String,
    district: String,
    gutter: {
      type: Number,
      default: 10
    },
    wholeCode: Boolean
  },
  data () {
    return {
      provinces: [],
      cities: [],
      districts: [],
      provinceId: '',
      cityId: '',
      districtId: '',
      settingState: false,

      pTag: '',
      cTag: '',
      aTag: ''
    }
  },
  watch: {
    provinceId (n) {
      if (this.settingState) return
      // const province = this.provinces.find(p => p.id === n)
      this.cityId = ''
      this.districtId = ''
      this.$emit('update:province', this.pTag)
      this.$emit('update:city', '')
      this.$emit('update:district', '')
    },
    cityId (n) {
      if (this.settingState) return
      // const city = this.cities.find(c => c.id === n)
      this.districtId = ''
      this.$emit('update:city', this.cTag)
      this.$emit('update:district', '')
    },
    districtId (n) {
      if (this.settingState) return
      // const district = this.districts.find(d => d.id === n)
      if (this.wholeCode) {
        this.$emit('update:district', this.pTag + this.cTag + this.aTag)
      } else {
        this.$emit('update:district', this.aTag)
      }
    }
  },
  methods: {
    getProvinces () {
      return new Promise(resolve => {
        dataCenter.getProvinces(this, (res, err) => {
          if (res) {
            this.provinces = res
            resolve()
          }
        })
      })
    },
    onProvinceChange (province) {
      if (province && province.value) {
        this.pTag = province.value.split('$')[1]
        province.value = province.value.split('$')[0]
        return new Promise(resolve => {
          dataCenter.getCities(this, province.value, (res, err) => {
            if (res) {
              this.cities = res
              resolve()
            }
          })
        })
      } else {
        this.cities = []
        this.districts = []
        this.cityId = ''
        this.districtId = ''
        this.pTag = ''
        this.cTag = ''
        this.aTag = ''
      }
    },
    onCityChange (city) {
      if (city && city.value) {
        this.cTag = city.value.split('$')[1]
        city.value = city.value.split('$')[0]
        return new Promise(resolve => {
          dataCenter.getDistricts(this, city.value, (res, err) => {
            if (res) {
              this.districts = res
              resolve()
            }
          })
        })
      } else {
        this.districts = []
        this.districtId = ''
        this.cTag = ''
        this.aTag = ''
      }
    },
    onDistrictChange (district) {
      if (district && district.value) {
        this.aTag = district.value.split('$')[1]
      } else {
        this.aTag = ''
      }
    },
    clearState () {
      this.provinceId = ''
      this.cityId = ''
      this.districtId = ''
    },
    async setState (province, city, district) {
      this.settingState = true
      try {
        if (this.provinces.length === 0) {
          await this.getProvinces()
        }
        const provinceObj = this.provinces.find(item => item.name === province)
        this.provinceId = provinceObj.id

        await this.onProvinceChange({ value: this.provinceId })
        const cityObj = this.cities.find(item => item.name === city)
        this.cityId = cityObj.id

        await this.onCityChange({ value: this.cityId })
        const districtObj = this.districts.find(item => item.name === district)
        this.districtId = districtObj.id
      } catch (err) {
        console.log(err)
      } finally {
        this.settingState = false
      }
    },
    handleClose (visible, field, ref) {
      if (!visible && !this[field] && this.$refs[ref]) {
        this.$refs[ref].setQuery(null)
      }
    }
  },
  created () {
    this.getProvinces()
  }
}
</script>